package com.egrand.sweetapi.modules.assertion;

import com.egrand.sweetapi.core.ModuleService;
import com.egrand.sweetapi.core.exception.AssertException;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.Collection;
import java.util.Map;
import java.util.function.Supplier;

/**
 * 断言
 */
public class AssertModule implements ModuleService {

    public void isNull(@Nullable Object object, String message) {
        if (object != null) {
            throw new AssertException(message);
        }
    }

    public void isNull(@Nullable Object object, Supplier<String> messageSupplier) {
        if (object != null) {
            throw new AssertException(nullSafeGet(messageSupplier));
        }
    }

    public void notNull(@Nullable Object object, String message) {
        if (object == null) {
            throw new AssertException(message);
        }
    }

    public void notNull(@Nullable Object object, Supplier<String> messageSupplier) {
        if (object == null) {
            throw new AssertException(nullSafeGet(messageSupplier));
        }
    }

    public void hasLength(@Nullable String text, String message) {
        if (!StringUtils.hasLength(text)) {
            throw new AssertException(message);
        }
    }

    public void hasLength(@Nullable String text, Supplier<String> messageSupplier) {
        if (!StringUtils.hasLength(text)) {
            throw new AssertException(nullSafeGet(messageSupplier));
        }
    }

    public void hasText(@Nullable String text, String message) {
        if (!StringUtils.hasText(text)) {
            throw new AssertException(message);
        }
    }

    public void hasText(@Nullable String text, Supplier<String> messageSupplier) {
        if (!StringUtils.hasText(text)) {
            throw new AssertException(nullSafeGet(messageSupplier));
        }
    }

    public void notEmpty(@Nullable Object[] array, String message) {
        if (ObjectUtils.isEmpty(array)) {
            throw new AssertException(message);
        }
    }

    public void notEmpty(@Nullable Object[] array, Supplier<String> messageSupplier) {
        if (ObjectUtils.isEmpty(array)) {
            throw new AssertException(nullSafeGet(messageSupplier));
        }
    }

    public void notEmpty(@Nullable Collection<?> collection, String message) {
        if (CollectionUtils.isEmpty(collection)) {
            throw new AssertException(message);
        }
    }

    public void notEmpty(@Nullable Collection<?> collection, Supplier<String> messageSupplier) {
        if (CollectionUtils.isEmpty(collection)) {
            throw new AssertException(nullSafeGet(messageSupplier));
        }
    }

    public void notEmpty(@Nullable Map<?, ?> map, String message) {
        if (CollectionUtils.isEmpty(map)) {
            throw new AssertException(message);
        }
    }

    public void notEmpty(@Nullable Map<?, ?> map, Supplier<String> messageSupplier) {
        if (CollectionUtils.isEmpty(map)) {
            throw new AssertException(nullSafeGet(messageSupplier));
        }
    }

    public void isTrue(boolean expression, String msg) {
        if (!expression) {
            throw new AssertException(msg);
        }
    }

    public void isTrue(boolean expression, Supplier<String> messageSupplier) {
        if (!expression) {
            throw new AssertException(nullSafeGet(messageSupplier));
        }
    }

    public void regex(String regex, String input, String msg){
        boolean validate = input == null ? false : input.matches(regex);
        if (!validate){
            throw new AssertException(msg);
        }
    }

    public void regex(String regex, String input, Supplier<String> messageSupplier){
        boolean validate = input == null ? false : input.matches(regex);
        if (!validate){
            throw new AssertException(nullSafeGet(messageSupplier));
        }
    }

    @Nullable
    private static String nullSafeGet(@Nullable Supplier<String> messageSupplier) {
        return messageSupplier != null ? (String)messageSupplier.get() : null;
    }

    @Override
    public String getType() {
        return "assert";
    }
}
